package cn.wizzer.app.user.modules.service.impl;

import cn.wizzer.app.sys.modules.models.SysCollectBank;
import cn.wizzer.app.sys.modules.models.SysMsg;
import cn.wizzer.app.sys.modules.services.SysCollectBankService;
import cn.wizzer.app.sys.modules.services.SysMsgService;
import cn.wizzer.app.user.modules.models.UserRecharge;
import cn.wizzer.app.user.modules.models.enums.BizTypeEnum;
import cn.wizzer.app.user.modules.models.enums.ChannelEnum;
import cn.wizzer.app.user.modules.models.vo.UserRechargeVo;
import cn.wizzer.app.user.modules.services.UserService;
import cn.wizzer.app.user.modules.services.account.UserAccountRecordService;
import cn.wizzer.app.user.modules.services.account.UserRechargeService;
import cn.wizzer.framework.base.Result;
import cn.wizzer.framework.base.exceptions.BizException;
import cn.wizzer.framework.base.service.BaseServiceImpl;
import cn.wizzer.framework.base.service.CommonDBService;
import cn.wizzer.framework.page.Pagination;
import cn.wizzer.framework.util.Id;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;

import java.math.BigDecimal;
import java.util.List;
import java.util.Random;

@IocBean(args = {"refer:dao"})
@Service(interfaceClass = UserRechargeService.class)
public class UserRechargeServiceImpl extends BaseServiceImpl<UserRecharge> implements UserRechargeService {

    public UserRechargeServiceImpl(Dao dao) {
        super(dao);
    }

    @Inject
    private UserAccountRecordService recordService;

    @Inject
    private UserService userService;

    @Inject
    private CommonDBService commonDBService;

    @Inject
    @Reference
    private SysCollectBankService bankService;

    @Inject
    @Reference
    private SysMsgService userMsgService;

    @Override
    public UserRecharge add(BigDecimal amount, String appid, ChannelEnum channel) {
        if(BigDecimal.ZERO.compareTo(amount)>=0){
            Result.breakWith("请确保您的行为安全");
        }
        UserRecharge recharge = new UserRecharge();
        //待后台确认
        recharge.setStatus(0);
        recharge.setUserId(appid);
        recharge.setCtAt(System.currentTimeMillis());
        recharge.setAmount(amount);
        recharge.setChannel(channel);
        recharge.setSign(String.valueOf(new Random().nextInt(9000)+1000));
        recharge.setNo(Id.createOrderNo());
        List<SysCollectBank> usable = bankService.query(Cnd.where("disabled", "=", false));
        if (usable.size()==0) {
            Result.breakWith("充值通道已关闭");
        }
        SysCollectBank bank = usable.get(usable.size()==1?0:new Random().nextInt(usable.size() - 1));
        recharge.setBankId(bank.getId());
        this.insert(recharge);
        recharge.setCollectBank(bank);
        return recharge;
    }

    @Override
    public void manual(BigDecimal amount, String toUser, String updaterId) {
        UserRecharge recharge = new UserRecharge();
        recharge.setAmount(amount);
        //手动
        recharge.setChannel(ChannelEnum.MANUAL);
        recharge.setSign("0000");
        recharge.setNo(Id.createOrderNo());
        recharge.setUserId(toUser);
        recharge.setStatus(1);
        recharge.setOpBy(updaterId);
        this.insert(recharge);
        //到账。。直接到
        sure(recharge.getId(),true,updaterId);
    }

    @Override
    public Pagination listPage(String orderNo, String searchKeyword, String[] searchDate, Integer status,
                               ChannelEnum channel, int pageNumber, int pageSize) {
        Sql sql = Sqls.create("SELECT r.*, u.userName, u.`nickName`, u.`phone`,b.card_no,b.name as account_name " +
                "FROM user_recharge r ");
        Sql countSql = Sqls.create("SELECT COUNT(1) FROM user_recharge r ");
        Sql joinSql = Sqls.create("LEFT JOIN USER u ON u.id = r.user_id " +
                "LEFT JOIN sys_collect_bank b ON b.id = r.bank_id " +
                "$condition ");
        Cnd cnd = Cnd.where("r.delFlag", "=", 0);
        if(Strings.isNotBlank(orderNo)){
            orderNo = "%" + orderNo + "%";
            cnd.and("r.no", "LIKE", orderNo);
        }
        if(Strings.isNotBlank(searchKeyword)){
            searchKeyword = "%" + searchKeyword + "%";
            cnd.and(Cnd.exps("u.nickName", "LIKE", searchKeyword)
                    .or("u.phone", "LIKE", searchKeyword)
                    .or("u.userName", "LIKE", searchKeyword));
        }
        if(searchDate != null && searchDate.length > 0){
            cnd.and("r.ctAt", ">=", Times.d2TS(Times.D(searchDate[0])));
            cnd.and("r.ctAt", "<=", Times.d2TS(Times.D(searchDate[1])));
        }
        if(status != null){
            cnd.and("r.status", "=", status);
        }
        if(channel != null){
            cnd.and("r.channel", "=", channel);
        }
        joinSql.setCondition(cnd);
        sql.appendSourceSql(joinSql.toString());
        sql.appendSourceSql("ORDER BY r.ctAt DESC");
        countSql.appendSourceSql(joinSql.toString());
        return commonDBService.listPage(UserRechargeVo.class, pageNumber, pageSize, sql.toString(), countSql.toString());
    }

    @Aop(TransAop.REPEATABLE_READ)
    @Override
    public void sure(String id, Boolean sure, String opBy) {

        UserRecharge record = this.fetch(id);
        if(record.getStatus()!=1){
            throw new BizException("该单已操作");
        }
        record.setOpBy(opBy);
        String title;
        String result;
        if (sure) {
            //已完成
            record.setStatus(2);
            recordService.add(record.getUserId(), record.getAmount(), BizTypeEnum.RECHARGE, id);
            title = "充值到账提醒";
            result = "成功";
        } else {
            //失败
            record.setStatus(3);
            title = "充值失败通知";
            result = "失败";
        }
        //构建消息通知
        SysMsg userMsg = userMsgService.createMsg("member", title, String.format("<p>您的钻石购买" + result + "，订单号<span style='color:red'>[%s]</span>，" +
                        "数量<span style='color:red'>[%s]</span>，充值方式<span style='color:red'>[%s]</span></p>",
                record.getNo(), record.getAmount(), record.getChannel().NAME), opBy);
        //发送消息给用户
        userMsgService.saveMsg(userMsg,new String[]{record.getUserId()});
        this.update(record);
    }

    @Override
    public UserRecharge detail(String where) {
        StringBuffer sb = new StringBuffer();
        sb.append("SELECT r.*,u.`nickName`,u.`phone`,b.card_no,b.name as account_name,b.bank_name,b.sub_branch FROM user_recharge r ")
                .append("LEFT JOIN USER u ON u.id = r.user_id ")
                .append("LEFT JOIN sys_collect_bank b ON b.id = r.bank_id ")
                .append(where)
                .append(" order by r.opAt desc");
        return commonDBService.fetchSql(UserRechargeVo.class, sb.toString());
    }

}
